package com.hfuu.service.impl;

import com.hfuu.dao.read.custom.TbScheduleReadDao;
import com.hfuu.dao.read.custom.TbUserReadDao;
import com.hfuu.dao.read.custom.TbUserScheduleReadDao;
import com.hfuu.dao.write.custom.TbCheckRecordWriteDao;
import com.hfuu.dao.write.custom.TbUserScheduleWriteDao;
import com.hfuu.dao.write.custom.TbUserWriteDao;
import com.hfuu.enums.system.ExceptionEnum;
import com.hfuu.exceptions.ServiceExceptionSpec;
import com.hfuu.model.po.*;
import com.hfuu.service.user.UserService;
import com.hfuu.service.user.request.ManSysUserRequest;
import com.hfuu.service.user.request.UserLoginRequest;
import com.hfuu.service.user.request.UserRequest;
import com.hfuu.service.user.response.UserLoginResponse;
import com.hfuu.utils.GetIpAddressUtil;
import com.hfuu.utils.RandomValidateUtil;
import com.hfuu.utils.SignUtils;
import com.hfuu.utils.UUIDGenerateUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.List;

/**
 * 用户注册登录类
 */
@Service
public class UserServiceImpl implements UserService{

    private Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);

    @Autowired
    private TbUserWriteDao tbUserWriteDao;

    @Autowired
    private TbCheckRecordWriteDao tbCheckRecordWriteDao;

    @Autowired
    private TbUserReadDao tbUserReadDao;

    @Autowired
    private TbScheduleReadDao tbScheduleReadDao;

    @Autowired
    private TbUserScheduleWriteDao tbUserScheduleWriteDao;

    @Autowired
    private TbUserScheduleReadDao tbUserScheduleReadDao;

    /**
     * 用户注册和资料更新，如果不是普通用户，需要进行审核
     * @param request
     * @return
     * @throws ServiceExceptionSpec
     */
    @Override
    public TbUser insertOrUpdateUser(UserRequest request) throws ServiceExceptionSpec {
        if (StringUtils.isBlank(request.getUserName())
                || request.getUserRole() == null) {
            throw new ServiceExceptionSpec(ExceptionEnum.USER_BASE_PARAMS_ILLEGAL);
        }
        TbUser tbUser = new TbUser();
        BeanUtils.copyProperties(request, tbUser);
        if (StringUtils.isNotBlank(request.getPassWord())) {
            tbUser.setPassWord(SignUtils.generateMd5(request.getPassWord()));
        } else {
            tbUser.setPassWord(null);
        }
        //判断用户角色
        if (request.getUserRole() == 1) {
            tbUser.setStatus(1);
        }
        if (tbUser.getId() == null) {
            tbUserWriteDao.insertSelective(tbUser);
            if (request.getUserRole() > 1) {
                //插入待审核表中
                TbCheckRecord tbCheckRecord = new TbCheckRecord();
                tbCheckRecord.setUserId(tbUser.getId());
                tbCheckRecord.setType(1);
                tbCheckRecord.setFinish(1);
                tbCheckRecordWriteDao.insertSelective(tbCheckRecord);
            }
        } else {
            tbUserWriteDao.updateByPrimaryKeySelective(tbUser);
            //用户完善个人信息时，进行初始化空闲课程表
            if (request.getUserRole() == 1) {
                String school = request.getSchool();
                String grade = request.getGrade();
                String major = request.getMajor();
                //如果TbUserSchedule中已有数据，则不用新增了
                TbUserScheduleExample example1 = new TbUserScheduleExample();
                TbUserScheduleExample.Criteria criteria1 = example1.createCriteria();
                criteria1.andDisabledEqualTo(0).andSchoolEqualTo(school)
                        .andGradeEqualTo(grade).andMajorEqualTo(major).andUserIdEqualTo(tbUser.getId());
                List<TbUserSchedule> tbUserSchedules = tbUserScheduleReadDao.selectByExample(example1);
                if (!CollectionUtils.isEmpty(tbUserSchedules)) {
                    return tbUser;
                }

                //没有该班级信息，则进行新增TbUserSchedule数据
                TbScheduleExample example = new TbScheduleExample();
                TbScheduleExample.Criteria criteria = example.createCriteria();
                criteria.andDisabledEqualTo(0).andSchoolEqualTo(school)
                        .andGradeEqualTo(grade).andMajorEqualTo(major);
                List<TbSchedule> lists = tbScheduleReadDao.selectByExample(example);
                if (!CollectionUtils.isEmpty(lists)) {
                    for (TbSchedule tbSchedule : lists) {
                        TbUserSchedule tbUserSchedule = new TbUserSchedule();
                        BeanUtils.copyProperties(tbSchedule, tbUserSchedule);
                        tbUserSchedule.setUserId(tbUser.getId());
                        tbUserSchedule.setId(null);
                        tbUserScheduleWriteDao.insertSelective(tbUserSchedule);
                    }
                }
            }
        }
        return tbUser;
    }


    /**
     * 用户后台登录
     * @param request
     * @param sysLoginRequest
     * @return
     * @throws ServiceExceptionSpec
     */
    @Override
    public UserLoginResponse sysLogin(HttpServletRequest request, UserLoginRequest sysLoginRequest) throws ServiceExceptionSpec {
        // 参数判断
        String userName = sysLoginRequest.getUserName();
        String passWord = sysLoginRequest.getPassWord();
        if(StringUtils.isEmpty(userName)
                || StringUtils.isEmpty(passWord)){
            throw new ServiceExceptionSpec(ExceptionEnum.USER_LOGIN_ERROR);
        }
        //数据查询
        TbUserExample example = new TbUserExample();
        TbUserExample.Criteria criteria = example.createCriteria();
        criteria.andDisabledEqualTo(0);
        criteria.andStatusEqualTo(1);
        criteria.andUserNameEqualTo(userName);
        criteria.andPassWordEqualTo(SignUtils.generateMd5(passWord));

        //结果处理
        UserLoginResponse response = new UserLoginResponse();
        List<TbUser> result = tbUserReadDao.selectByExample(example);
        if (CollectionUtils.isEmpty(result)
                || result.get(0) == null) {
            throw new ServiceExceptionSpec(ExceptionEnum.USER_LOGIN_ERROR);
        }
        TbUser userInfo = result.get(0);

        //获取登录用户最近一次登录ip，以及登录时间
        TbUser updateUser = new TbUser();
        updateUser.setId(userInfo.getId());
        updateUser.setLastLoginTime(new Date());
        String ipAddr = GetIpAddressUtil.getIpAddr(request);
        updateUser.setIpAddr(ipAddr);
        tbUserWriteDao.updateByPrimaryKeySelective(updateUser);

        response.setRealName(userInfo.getRealName());
        response.setUserName(userInfo.getUserName());
        response.setId(userInfo.getId());
        response.setUserRole(userInfo.getUserRole());
        response.setSessionId(UUIDGenerateUtil.uuid());
        return response;
    }

    /**
     * 注销用户
     * @param request
     * @param sysLoginRequest
     * @return
     */
    @Override
    public Object userDisable(HttpServletRequest request, UserLoginRequest sysLoginRequest)
            throws ServiceExceptionSpec{

        if (sysLoginRequest.getId() == null) {
            throw new ServiceExceptionSpec(ExceptionEnum.USER_LOGOUT_ERROR);
        }
        TbUser tbUser = new TbUser();
        tbUser.setDisabled(1);
        tbUser.setId(sysLoginRequest.getId());
        tbUserWriteDao.updateByPrimaryKeySelective(tbUser);
        return null;
    }

    @Override
    public String getCheckImage(HttpServletRequest request, HttpServletResponse response) {
        response.setContentType("image/jpeg");// 设置相应类型,告诉浏览器输出的内容为图片
        response.setHeader("Pragma", "No-cache");// 设置响应头信息，告诉浏览器不要缓存此内容
        response.setHeader("Cache-Control", "no-cache");
        response.setHeader("Set-Cookie", "HttpOnly =、 false; ");//设置HttpOnly属性,防止Xss攻击
        response.setDateHeader("Expire", 0);
        RandomValidateUtil randomValidateCode = new RandomValidateUtil();
        try {
            // 输出图片方法
            randomValidateCode.getRandCode(request, response,"imagecode");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    @Override
    public boolean judgeCheckCode(HttpServletRequest request,
                                  UserLoginRequest userLoginRequest) {

        String checkCode = userLoginRequest.getUserName();
        Cookie[] cookies = request.getCookies();
        for (Cookie cookie : cookies) {
            if ("imagecode".equals(cookie.getName())) {
                if (checkCode.equals(cookie.getValue())) {
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    public boolean judgeUserName(HttpServletRequest request,
                                 UserLoginRequest userLoginRequest) {
        String userName = userLoginRequest.getUserName();
        TbUserExample tbUserExample = new TbUserExample();
        TbUserExample.Criteria criteria = tbUserExample.createCriteria();
        criteria.andDisabledEqualTo(0).andUserNameEqualTo(userName);
        List<TbUser> tbUsers = tbUserReadDao.selectByExample(tbUserExample);
        if (CollectionUtils.isEmpty(tbUsers)) {
            return true;
        }
        return false;
    }

    /**
     * 修改用户的密码
     */
    @Override
    public void updateSysUserPasswd(ManSysUserRequest userRequest)
            throws Exception {
        if(userRequest.getId() == null || StringUtils.isEmpty(userRequest.getOldPassword()) ||
                StringUtils.isEmpty(userRequest.getNewPassword())){
            throw new ServiceExceptionSpec(ExceptionEnum.USER_BASE_PARAMS_ILLEGAL);
        }
        TbUserExample tbUser = new TbUserExample();
        TbUserExample.Criteria criteria = tbUser.createCriteria();
        criteria.andDisabledEqualTo(0).andIdEqualTo(userRequest.getId())
                .andPassWordEqualTo(SignUtils.generateMd5(userRequest.getOldPassword()));
        List<TbUser> searchResult = tbUserReadDao.selectByExample(tbUser);
        if (CollectionUtils.isEmpty(searchResult)) {
            throw new ServiceExceptionSpec(ExceptionEnum.USER_PASSWORD_ERROR);
        }
        TbUser search = searchResult.get(0);
        search.setPassWord(SignUtils.generateMd5(userRequest.getNewPassword()));
        search.setUpdateTime(new Date());
        tbUserWriteDao.updateByPrimaryKey(search);
    }

    @Override
    public Object getUserById(HttpServletRequest request,
                              UserLoginRequest userLoginRequest) throws Exception{

        if (userLoginRequest.getId() == null ) {
            throw new ServiceExceptionSpec(ExceptionEnum.USER_BASE_PARAMS_ILLEGAL);
        }

        TbUser user = tbUserReadDao.selectByPrimaryKey(userLoginRequest.getId());
        user.setPassWord("");
        return user;
    }
}
